package com.yf.ability.face.provides.baidu.service.impl;

import com.alibaba.fastjson.JSON;
import com.baidu.aip.face.AipFace;
import com.yf.ability.config.dto.CfgPropDTO;
import com.yf.ability.config.enums.ConfigType;
import com.yf.ability.config.enums.ProviderType;
import com.yf.ability.config.service.CfgPropService;
import com.yf.base.api.exception.ServiceException;
import com.yf.base.utils.DecimalUtils;
import org.apache.commons.lang3.StringUtils;
import com.yf.ability.face.provides.baidu.config.BaiduFaceConfig;
import com.yf.ability.face.provides.baidu.dto.BaiduFaceSearchResponse;
import com.yf.ability.face.enums.FaceImageType;
import com.yf.ability.face.service.ThirdFaceService;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;

@Service("baiduFaceService")
public class BaiduFaceServiceImpl implements ThirdFaceService {


    @Autowired
    private CfgPropService cfgPropService;


    @Override
    public void addFace(String imageType, String image, String userId) {


        // 获取配置
        BaiduFaceConfig cfg = this.getConfig();

        // 添加一个人脸
        JSONObject res = this.getClient(cfg).addUser(image, imageType, cfg.getFaceGroup(), userId, new HashMap<>());
        System.out.println(res.toString(2));

        // 处理结果
        BaiduFaceSearchResponse response = JSON.parseObject(res.toString(), BaiduFaceSearchResponse.class);

        // 响应结果
        Integer code = response.getErrorCode();

        if(!code.equals(0)){

            if(code.equals(222202)){
                throw new ServiceException("未识别到人脸，请上传带人脸的照片！" );
            }

            throw new ServiceException("人脸添加失败：" + response.getErrorMsg());
        }

    }

    @Override
    public void deleteFace(String userId) {

        // 获取配置
        BaiduFaceConfig cfg = this.getConfig();

        // 删除人脸
        JSONObject res = this.getClient(cfg).deleteUser(cfg.getFaceGroup(), userId, new HashMap<>());

        // 处理结果
        BaiduFaceSearchResponse response = JSON.parseObject(res.toString(), BaiduFaceSearchResponse.class);
        Integer code = response.getErrorCode();
        // 0表示正确，223103表示人脸不存在可忽略此错误
        if(!code.equals(0) && !code.equals(223103)){
            throw new ServiceException("人脸删除失败：" + response.getErrorMsg());
        }
    }

    @Override
    public void updateFace(String imageType, String image, String userId) {

        // 获取配置
        BaiduFaceConfig cfg = this.getConfig();

        // 添加一个人脸
        JSONObject res = this.getClient(cfg).updateUser(image, imageType, cfg.getFaceGroup(), userId, new HashMap<>());
        System.out.println(res.toString(2));

        // 处理结果
        BaiduFaceSearchResponse response = JSON.parseObject(res.toString(), BaiduFaceSearchResponse.class);

        Integer code = response.getErrorCode();


        if(!code.equals(0)){

            if(code.equals(222202)){
                throw new ServiceException("未识别到人脸，请上传带人脸的照片！" );
            }

            // 用户不存在的情形，新增人脸
            if(code.equals(223103)){
                this.addFace(imageType, image, userId);
                return;
            }

            throw new ServiceException("人脸更新失败：" + response.getErrorMsg());
        }
    }

    /**
     * 搜索人脸
     * @param imageType
     * @param image
     * @return
     */
    @Override
    public String searchFace(String imageType, String image){

        // 获取配置
        BaiduFaceConfig cfg = this.getConfig();

        // 获取结果
        JSONObject res = this.getClient(cfg).search(image, imageType, cfg.getFaceGroup(), new HashMap<>());

        // 判断识别状态
        BaiduFaceSearchResponse response = JSON.parseObject(res.toString(), BaiduFaceSearchResponse.class);

        System.out.println("+++++++++搜索结果为：\n"+JSON.toJSONString(response));

        if(response.getResult() == null){
            throw new ServiceException("未找到匹配的人脸！");
        }

        List<BaiduFaceSearchResponse.User> userList = response.getResult().getUserList();
        if(!CollectionUtils.isEmpty(userList)){
            for(BaiduFaceSearchResponse.User item: userList){
                if(DecimalUtils.ge(item.getScore(), 80.0)){
                    return item.getUserId();
                }
            }
        }

        throw new ServiceException("识别失败，未找到匹配的人脸！");
    }

    @Override
    public void mergeFace(boolean isAdd, String oldFace, String newFace, String userId) {


        // 添加模式
        if(isAdd){
            if(!StringUtils.isBlank(newFace)){
                // 直接添加
                this.addFace(FaceImageType.URL, newFace, userId);
            }
        }else{

            // 清空，删除人脸
            if(StringUtils.isBlank(newFace) && !StringUtils.isBlank(oldFace)){
                this.deleteFace(userId);
                return;
            }

            // 添加过，更新
            if(!StringUtils.isBlank(newFace) && !StringUtils.isBlank(oldFace)){
                this.updateFace(FaceImageType.URL, newFace, userId);
                return;
            }

            // 未添加过，增加
            if(!StringUtils.isBlank(newFace) && StringUtils.isBlank(oldFace)){
                this.addFace(FaceImageType.URL, newFace, userId);
                return;
            }
        }
    }

    /**
     * 获取配置文件
     * @return
     */
    private BaiduFaceConfig getConfig(){
        CfgPropDTO dto = cfgPropService.detail(ConfigType.FACE, ProviderType.BAIDU);
        BaiduFaceConfig cfg = JSON.parseObject(dto.getData(), BaiduFaceConfig.class);
        return cfg;
    }


    /**
     * 获取API接口
     * @return
     */
    private AipFace getClient(BaiduFaceConfig cfg){

        // 初始化一个AipFace
        AipFace client = new AipFace(cfg.getAppId(), cfg.getAppKey(), cfg.getSecretKey());

        // 可选：设置网络连接参数
        client.setConnectionTimeoutInMillis(2000);
        client.setSocketTimeoutInMillis(60000);

        return client;
    }
}
